﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using System.Threading;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Threading;
using TfL;

namespace Tfl.Controls.WPF.ViewModel
{
    public class DesignTimeStationIncidentsViewModel : StationIncidentsViewModel
    {
        public DesignTimeStationIncidentsViewModel()
        {
            Title = "Design Time";
            Incidents = new ObservableCollection<StationIncidentViewModel>(new StationIncidentViewModel[]
                                                                               {
                                                                                   new StationIncidentViewModel{Description = "description",Name="Victoria",Status ="Broken"} 
                                                                               });
        }
    }

    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class StationIncidentsViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the StationIncidentsViewModel class.
        /// </summary>
        public StationIncidentsViewModel()
        {
            ////if (IsInDesignMode)
            ////{
            ////    // Code runs in Blend --> create design time data.
            ////}
            ////else
            ////{
            ////    // Code runs "for real": Connect to service, etc...
            ////}
        }

        public StationIncidentsViewModel(IStationStatusFeed feed)
        {
            DispatcherHelper.Initialize();
            Title = "Run time";
            _feed = feed;
            _tokenSource = new CancellationTokenSource();
            _stationIncidents = new ObservableCollection<StationIncidentViewModel>();
            _stationIncidents.CollectionChanged += StationIncidentsCollectionChanged;
            var incidents = from i in _feed.IncidentsOnly.Poll(_tokenSource.Token, 30000)
                            select i;
            _subscriber = incidents.Subscribe(OnNext);
        }
        
        public override void Cleanup()
        {
            // Clean own resources if needed

            base.Cleanup();
            _subscriber.Dispose();
            _tokenSource.Cancel();
        }

        public string Title
        {
            get
            {
                return _title;
            }
            set
            {
                _title = value;
                RaisePropertyChanged("Title");
            }
        }

        public ObservableCollection<StationIncidentViewModel> Incidents
        {
            get 
            { 
                return _stationIncidents; 
            }
            set 
            {
                _stationIncidents = value;
                RaisePropertyChanged("Incidents");
            }
        }

        private void OnNext(List<StationStatus> list)
        {
            if(list == null)
            {
                DispatcherHelper.CheckBeginInvokeOnUI(()=>_stationIncidents.Clear());
                Title = string.Format("Station Incidents - Latest Update {0}", DateTime.Now);
            }
            else
            {
                list.ForEach((status) =>
                {
                    var svm = new StationIncidentViewModel
                    {
                        Name = status.Station.Name,
                        Description = status.StatusDetails,
                        Status = status.Status.Description
                    };

                    DispatcherHelper.CheckBeginInvokeOnUI(() => _stationIncidents.Add(svm));
                });
            }

        }

        void StationIncidentsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            RaisePropertyChanged("Incidents");
        }

        private readonly IStationStatusFeed _feed;
        private string _title = string.Empty;
        private readonly CancellationTokenSource _tokenSource;
        private ObservableCollection<StationIncidentViewModel> _stationIncidents;
        private readonly IDisposable _subscriber;

        
    }
}